package com.ethink.warehouse.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ethink.framework.common.constant.CommonRespCode;
import com.ethink.framework.common.db.PageUtils;
import com.ethink.framework.common.exception.BusinessException;
import com.ethink.id.generator.IdGenerator;
import com.ethink.warehouse.api.enums.LogisticsTraceApplyOrderOrderStatusEnum;
import com.ethink.warehouse.api.enums.SubjectEnum;
import com.ethink.warehouse.api.info.MateInventoryDetailInfo;
import com.ethink.warehouse.api.info.SubWarehouseInfo;
import com.ethink.warehouse.api.request.*;
import com.ethink.warehouse.api.response.*;
import com.ethink.warehouse.common.entity.LogisticsTraceApplyOrder;
import com.ethink.warehouse.common.mapper.LogisticsTraceApplyDetailOrderMapper;
import com.ethink.warehouse.common.mapper.LogisticsTraceApplyOrderMapper;
import com.ethink.warehouse.common.mapper.MateInventoryMapper;
import com.ethink.warehouse.converter.LogisticsTraceApplyOrderConverter;
import com.ethink.warehouse.service.LogisticsTraceApplyOrderService;
import com.ethink.warehouse.service.SubWarehouseService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 物流跟进申请表 Service接口实现
 *
 * @author default
 * @date 2022-12-15
 */
@Slf4j
@Service
public class LogisticsTraceApplyOrderServiceImpl extends ServiceImpl<LogisticsTraceApplyOrderMapper, LogisticsTraceApplyOrder> implements LogisticsTraceApplyOrderService {

    @Autowired
    private LogisticsTraceApplyOrderMapper logisticsTraceApplyOrderMapper;

    @Autowired
    private LogisticsTraceApplyDetailOrderMapper logisticsTraceApplyDetailOrderMapper;

    @Autowired
    private LogisticsTraceApplyOrderConverter logisticsTraceApplyOrderConverter;

    @Autowired
    private SubWarehouseService subWarehouseService;

    @Autowired
    private IdGenerator idGenerator;

    @Autowired
    private MateInventoryMapper mateInventoryMapper;

    @Override
    public Page<LogisticsTraceApplyOrderQueryResponse> queryLogisticsTraceApplyOrder(LogisticsTraceApplyOrderQueryRequest request) {
        return logisticsTraceApplyOrderMapper.queryLogisticsTraceApplyOrder(PageUtils.buildPage(request), request);
    }

    @Override
    public List<LogisticsTraceApplyOrderQueryResponse> listLogisticsTraceApplyOrder(LogisticsTraceApplyOrderListRequest request) {
        return logisticsTraceApplyOrderMapper.listLogisticsTraceApplyOrder(request);
    }

    @Override
    public LogisticsTraceApplyOrderGetDetailResponse getLogisticsTraceApplyOrderById(Long logisticsTraceApplyOrderId) {
        return logisticsTraceApplyOrderMapper.getLogisticsTraceApplyOrderById(logisticsTraceApplyOrderId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public LogisticsTraceApplyAddResponse addLogisticsTraceApplyOrder(LogisticsTraceApplyAddRequest addRequest) {
        List<LogisticsTraceApplyOrder> logisticsTraceApplyOrderList = new ArrayList<>();
        Map<String, SubWarehouseInfo> subWarehouseInfoMap = subWarehouseService.listSubWarehouseMap();
        // 采购入库
        if (CollectionUtils.isNotEmpty(addRequest.getT11Items())) {
            for (LogisticsTraceApplyAddRequest.T11Item item : addRequest.getT11Items()) {
                LogisticsTraceApplyOrder applyOrder = buildBase(addRequest);
                // 明细信息
                BeanUtils.copyProperties(item, applyOrder);
                applyOrder.setSourceSubWarehouseCode(item.getSubWarehouseCode());
                applyOrder.setSourceSubWarehouseName(subWarehouseInfoMap.get(applyOrder.getSourceSubWarehouseCode()).getSubWarehouseName());
                logisticsTraceApplyOrderList.add(applyOrder);
            }
        }
        // 采购退货
        if (CollectionUtils.isNotEmpty(addRequest.getT12Items())) {
            List<MateInventoryDetailInfo> list = mateInventoryMapper.listMateInventoryByIdList(addRequest.getT12Items()
                    .stream().map(LogisticsTraceApplyAddRequest.T12Item::getMateInventoryId).collect(Collectors.toList()));
            Map<Long, MateInventoryDetailInfo> map = list.stream().collect(Collectors.toMap(MateInventoryDetailInfo::getId, info -> info));
            for (LogisticsTraceApplyAddRequest.T12Item item : addRequest.getT12Items()) {
                LogisticsTraceApplyOrder applyOrder = buildBase(addRequest);
                // 明细信息
                BeanUtils.copyProperties(item, applyOrder);
                MateInventoryDetailInfo mateInventory = map.get(item.getMateInventoryId());
                applyOrder.setSourceSubWarehouseCode(mateInventory.getSubWarehouseCode());
                applyOrder.setSourceSubWarehouseName(subWarehouseInfoMap.get(applyOrder.getSourceSubWarehouseCode()).getSubWarehouseName());

                applyOrder.setSaleSubChannel(applyOrder.getSaleSubChannel());
                applyOrder.setMateSku(mateInventory.getMateSku());
                applyOrder.setInventoryType(mateInventory.getInventoryType());
                applyOrder.setSaleSubChannel(mateInventory.getSaleSubChannel());
                applyOrder.setPurchaseOrderNo(mateInventory.getPurchaseOrderNo());
                applyOrder.setPurchaseDetailOrderNo(mateInventory.getPurchaseDetailOrderNo());
                applyOrder.setCostPrice(mateInventory.getCostPrice());
                applyOrder.setPurchaseCode(mateInventory.getPurchaseCode());
                applyOrder.setProduceCode(mateInventory.getProduceCode());
                logisticsTraceApplyOrderList.add(applyOrder);
            }
        }
        // 销售出库
        if (CollectionUtils.isNotEmpty(addRequest.getSaleCkItems())) {
            List<MateInventoryDetailInfo> list = mateInventoryMapper.listMateInventoryByIdList(addRequest.getSaleCkItems()
                    .stream().map(LogisticsTraceApplyAddRequest.SaleCkItem::getMateInventoryId).collect(Collectors.toList()));
            Map<Long, MateInventoryDetailInfo> map = list.stream().collect(Collectors.toMap(MateInventoryDetailInfo::getId, info -> info));

            for (LogisticsTraceApplyAddRequest.SaleCkItem item : addRequest.getSaleCkItems()) {
                LogisticsTraceApplyOrder applyOrder = buildBase(addRequest);
                // 明细信息
                BeanUtils.copyProperties(item, applyOrder);
                MateInventoryDetailInfo mateInventory = map.get(item.getMateInventoryId());
                applyOrder.setSourceSubWarehouseCode(mateInventory.getSubWarehouseCode());
                applyOrder.setSourceSubWarehouseName(subWarehouseInfoMap.get(applyOrder.getSourceSubWarehouseCode()).getSubWarehouseName());
                applyOrder.setTargetSubWarehouseCode(item.getTargetSubWarehouseCode());
                applyOrder.setTargetSubWarehouseName(item.getTargetSubWarehouseName());

                applyOrder.setSaleSubChannel(applyOrder.getSaleSubChannel());
                applyOrder.setMateSku(mateInventory.getMateSku());
                applyOrder.setInventoryType(mateInventory.getInventoryType());
                applyOrder.setSaleSubChannel(mateInventory.getSaleSubChannel());
                applyOrder.setPurchaseOrderNo(mateInventory.getPurchaseOrderNo());
                applyOrder.setPurchaseDetailOrderNo(mateInventory.getPurchaseDetailOrderNo());
                applyOrder.setCostPrice(mateInventory.getCostPrice());
                applyOrder.setPurchaseCode(mateInventory.getPurchaseCode());
                applyOrder.setProduceCode(mateInventory.getProduceCode());
                logisticsTraceApplyOrderList.add(applyOrder);
            }
        }
        // 预售，销售退货入库
        if (CollectionUtils.isNotEmpty(addRequest.getSaleReturnRkItems())) {
            for (LogisticsTraceApplyAddRequest.SaleReturnRkItem item : addRequest.getSaleReturnRkItems()) {
                LogisticsTraceApplyOrder applyOrder = buildBase(addRequest);
                BeanUtils.copyProperties(item, applyOrder);
                // 明细信息
                BeanUtils.copyProperties(item, applyOrder);
//                applyOrder.setSourceDetailOrderNo();
//                applyOrder.setMateSku();
//                applyOrder.setInventoryType();
//                applyOrder.setApplyInQty();
//                applyOrder.setSaleSubChannel();
                applyOrder.setSourceSubWarehouseCode(item.getSubWarehouseCode());
                applyOrder.setSourceSubWarehouseName(subWarehouseInfoMap.get(applyOrder.getSourceSubWarehouseCode()).getSubWarehouseName());
//                applyOrder.setMateInventoryId();
//                applyOrder.setPurchaseCode();
//                applyOrder.setProduceCode();
//                applyOrder.setPurchaseOrderNo();
//                applyOrder.setPurchaseDetailOrderNo();
//                applyOrder.setCostPrice();
                logisticsTraceApplyOrderList.add(applyOrder);
            }
        }
        // 在插入之前查询防止重复
        if (CollectionUtils.isNotEmpty(logisticsTraceApplyOrderList)) {
            // 收集
            // 查
            Integer count = logisticsTraceApplyOrderMapper.selectCount(
                    Wrappers.<LogisticsTraceApplyOrder>lambdaQuery()
                            .in(LogisticsTraceApplyOrder::getSourceDetailOrderNo, logisticsTraceApplyOrderList.stream().map(LogisticsTraceApplyOrder::getSourceDetailOrderNo).collect(Collectors.toList()))
                            .eq(LogisticsTraceApplyOrder::getSourceOrderType, addRequest.getSourceOrderType())
            );
            if (count > 0) {
                throw new BusinessException(CommonRespCode.SYSTEM_ERR, "不可以添加重复的订单");
            }
        }
        saveBatch(logisticsTraceApplyOrderList);
        return new LogisticsTraceApplyAddResponse();
    }

    @Override
    public LogisticsTraceApplyAddResponse updateLogisticsTraceApplyOrder(LogisticsTraceApplyUpdateRequest updateRequest) {
        if (SubjectEnum.T11.getCode().equals(updateRequest.getSourceOrderType())) {
            LogisticsTraceApplyDetailListRequest listRequest = new LogisticsTraceApplyDetailListRequest();
            BeanUtils.copyProperties(updateRequest, listRequest);
            List<LogisticsTraceApplyDetailOrderGetDetailResponse> list = logisticsTraceApplyDetailOrderMapper.listLogisticsTraceApplyDetailOrder(listRequest);
            if (CollectionUtils.isNotEmpty(list)) {
                throw new BusinessException(CommonRespCode.SYSTEM_ERR, "已创建物流跟进单，不能修改仓库");
            }
            SubWarehouseInfo subWarehouseInfo = subWarehouseService.getSubWarehouseByCode(updateRequest.getSubWarehouseCode());
            logisticsTraceApplyOrderMapper.update(null, new LambdaUpdateWrapper<LogisticsTraceApplyOrder>()
                    .eq(LogisticsTraceApplyOrder::getSourceOrderType, updateRequest.getSourceOrderType())
                    .eq(LogisticsTraceApplyOrder::getSourceOrderNo, updateRequest.getSourceOrderNo())
                    .in(LogisticsTraceApplyOrder::getSourceDetailOrderNo, updateRequest.getSourceDetailOrderNoList())
                    .set(LogisticsTraceApplyOrder::getSourceSubWarehouseCode, updateRequest.getSubWarehouseCode())
                    .set(LogisticsTraceApplyOrder::getSourceSubWarehouseName, subWarehouseInfo.getSubWarehouseName())
            );
        }
        return new LogisticsTraceApplyAddResponse();
    }


    private LogisticsTraceApplyOrder buildBase(LogisticsTraceApplyAddRequest addRequest) {
        // 基础订单信息
        LogisticsTraceApplyOrder applyOrder = new LogisticsTraceApplyOrder();
        BeanUtils.copyProperties(addRequest, applyOrder);
        applyOrder.setApplyOrderNo(idGenerator.tsap());
        applyOrder.setOrderStatus(LogisticsTraceApplyOrderOrderStatusEnum.S1.getIntValue());
//        applyOrder.setOrderType();
//        applyOrder.setSourceOrderNo();
//        applyOrder.setSourceOrderType();
//        applyOrder.setSubject();
//        applyOrder.setCreateUserCode();
//        applyOrder.setCreateUserName();
//        applyOrder.setCompanyCode();
//        applyOrder.setCompanyName();
        return applyOrder;
    }

    @Override
    public List<LogisticsTraceOrderNoOrderDetailResponse> listLogisticsTraceOrderNoOrderDetail(LogisticsTraceOrderTypeOrderListRequest request) {
        return logisticsTraceApplyDetailOrderMapper.listLogisticsTraceOrderNoOrderDetail(request);
    }
}
